/*
 *  syscall.c
 *  
 */

#include "syscall.h"


int main (void){
	int modo;
	
	printf("==================================================\n");
	printf("Escolha o modo:\n");
	printf(" 1: Gerenciamento de Arquivos\n 2: Entrada e Saida\n 3: Memoria\n 4: Processos\n");
	printf("==================================================\n");
	scanf("%d",&modo);
	
	while (modo != 0) {		
		switch (modo) {
			case 1:
				printf("modo 1: Gerenciamento de Arquivos\n");
				arquivo();
				break;
			case 2:
				printf("modo 2\n");
				io();
				break;
			case 3:
				printf("modo 3\n");
				memoria();
				break;
			case 4:
				printf("modo 4\n");
				processo();
			default:
				printf("modo invalido\n");
				break;
		}
		printf("==================================================\n");
		printf("Escolha o modo:\n");
		printf("1: Gerenciamento de Arquivos\n 2: Entrada e Saida\n 3: Memoria\n 4: Processos\n");
		printf("==================================================\n");

		scanf("%d",&modo);

	}


	return 0;
}


void arquivo(){
	int file;
	char *texto;
	
	/*Abre o Arquivo texte.txt, se o arquivo não existir ele é criado*/
	file = open("teste.txt",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU);
	
	/*Verifica se consegui abrir o arquivo corretamente*/
	if(file == -1)
		perror("erro no arquivo!");
	else 
		printf("Arquivo aberto com sucesso\n");
	
	texto = "Testando System Calls\n";
	
	/*Escreve no Arquivo*/
	if(write(file,texto,23) ==-1)
		perror("Erro na escrita!");
	else 
		printf("Escreveu no arquivo\n");
	
	close(file);
}	


void io(){
	int count, desc;
    char array[500];
	
    desc=0; count=500;
	
    printf("Digite uma frase:\n");
    __fpurge(stdin);
    count = read(desc, array, count);   
	//le caracteres do teclado e armazena em array
	
    printf("Tamanho da frase digitada: %d\n", count-1);
	
    printf("Voce digitou:\n");
    
    if(ioperm(0x300, 3, 1)) {                
		//ativa permissão para as portas 300h, 301h e 302h
        write(desc, array, count);          
		//escreve caracteres lidos
    }    
	
    ioperm(0x300, 3, 0);	            
	//desativa permissão para as portas 300h, 301h e 302h

}

void memoria(){
	const int alloc_size = 0.1 * 1024 * 1024; 
    char* memory = malloc (alloc_size);            
	//Aloca espaço de endereço
    mlock (memory, alloc_size);          
	//Tranca o espaço alocado na memória RAM
	
    size_t i;
    size_t page_size = getpagesize ();
	
    for (i = 0; i < alloc_size; i += page_size) {
        memory[i] = 0;
        printf("memory[%d] %d\n", i, memory[i]);
    }
	
    munlock(memory, alloc_size);                                
	//Destranca o espaço alocado na memória RAM
	
    if (mprotect(memory, 1024, PROT_READ) == -1) {              
		//Verifica se ocorrerá erro
        perror("ERRO");
        exit(errno);
    }
	
}


void processo(){
	pid_t  pid;
	int Status; 
	pid = fork();
	
	
	/* Processo filho. 
	 * Se o fork() retorna 0 
	 * significa que esta no processo filho.
	 */
	if (pid == 0)
	{  
		int j;
		/* Conta de 0 a 9 */ 
		for (j = 0; j < 10; j++)
		{
			printf("Processo Filho: %d\n", j);
			sleep(1);
		}
		_exit(0); 
	}
	else if (pid > 0)
	{ 
		/* Processo Pai.
		 * Se o fork() retorna um numero positivo, 
		 * significa que esta no processo pai.
		 */
		int i;
		
		/* Espera o processo filho terminar*/
		
		wait(&Status);
		
		/* Conta de 0 a 9*/
		for (i = 0; i < 10; i++)
		{
			printf("Processo Pai: %d\n", i);
			sleep(1);
		}
		
	}
	else
	{   
		/* Erro:
		 * Se o fork() retorna um numero negativo, ocorreu um erro.
		 */
		fprintf(stderr, "can't fork, error %d\n", errno);
		exit(EXIT_FAILURE);
	}
}	
















